package pe.com.bbva.efcap.servidor.controller;

import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Calendar;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

import org.boris.expr.engine.DependencyEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import pe.com.bbva.efcap.servidor.bean.rating.RatingBean;
import pe.com.bbva.efcap.servidor.bean.rating.RatingClienteBean;
import pe.com.bbva.efcap.servidor.modelo.entidad.Cliente;
import pe.com.bbva.efcap.servidor.modelo.entidad.Simulacion;
import pe.com.bbva.efcap.servidor.servicio.ClienteService;
import pe.com.bbva.efcap.servidor.servicio.MotorFormulasService;
import pe.com.bbva.efcap.servidor.servicio.RatingService;
import pe.com.bbva.efcap.servidor.servicio.SimulacionService;
import pe.com.bbva.efcap.servidor.util.Constante;
import pe.com.bbva.efcap.servidor.util.Validador;
import pe.com.bbva.efcap.servidor.util.formulas.BasicEngineProvider;

@Component("procRatingMB") 
@Scope("view")
public class ProcesarRatingController  implements Serializable{

	private static final long serialVersionUID = 1L;

	private static final Logger LOGGER = LoggerFactory.getLogger(ProcesarRatingController.class);
	
	@Autowired
	private RatingService ratingService;
	
	@Autowired
	private ClienteService clienteService;
	
	@Autowired
	private SimulacionService simulacionService;
	
	@Autowired
	private MotorFormulasService motorFormulasService;
	
	private String numeroDocumento;
	private int tipoDocumento;
	private boolean mostrarInfo;
	private RatingClienteBean clienteBean;
	private RatingBean ratingBean;
	private String descripcionSimulacion;
	
	private String codigoCentral;
	private String ruc;
	
	@PostConstruct
	public void init() {
		LOGGER.info("Procesamiento del Rating");
		tipoDocumento = 1;
		mostrarInfo = false;
		clienteBean = new RatingClienteBean();		
	}
	
	public void buscarCliente(){
		LOGGER.info("buscar cliente");
		RatingClienteBean aux = null;
		FacesContext context = FacesContext.getCurrentInstance();
		switch (tipoDocumento) {
		case 1:
			if(Validador.validarNoNulo(numeroDocumento) 
					&& Validador.validarNoVacio(numeroDocumento) 
					&& Validador.validarLongitudExacta(numeroDocumento, Constante.VALIDA_TAMANIO_RUC)){
				try{
					aux = ratingService.obtenerClientePorRuc(numeroDocumento);
					codigoCentral = aux.getCodigoCentral();
				}catch(NullPointerException e1){
					context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER003));
					return ;
				}catch(Exception e2){
					context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER002));
					LOGGER.debug(Constante.EXECPCION_ENCONTRADA + e2.toString(), e2);
					return ;
				}
			}else{
				context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER001));
				return ;
			}
			break;
		case 2:
			if(Validador.validarNoNulo(numeroDocumento) 
					&& Validador.validarNoVacio(numeroDocumento) 
					&& Validador.validarLongitudExacta(numeroDocumento, Constante.VALIDA_TAMANIO_CODIGO_CENTRAL)){
				try{
					codigoCentral = numeroDocumento;
					aux = ratingService.obtenerClientePorCodigoCentral(codigoCentral);
				}catch(NullPointerException e1){
					context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER003));
					return ;
				}catch(Exception e2){
					context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER002));
					LOGGER.debug(Constante.EXECPCION_ENCONTRADA + e2.toString(), e2);
					return ;
				}
			}else{
				context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER001));
				return ;
			}
			break;
		}
		try{
			ratingBean = ratingService.obtenerRating(codigoCentral, Constante.NUM_PERIODOS);
			clienteBean = ratingBean.getCliente();
			clienteBean.setCodigoCentral(aux.getCodigoCentral());
			clienteBean.setRuc(aux.getRuc());
			System.out.println("Cliente Bean: "+clienteBean);
			mostrarInfo = true;
		}catch(NullPointerException e3){
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER003));
			return ;
		}catch(Exception e4){
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER005));
			LOGGER.debug(Constante.EXECPCION_ENCONTRADA + e4.toString(), e4);
			return ;
		}
	}

	public String procesarRating(){
		LOGGER.info("Procesar rating");
		FacesContext context = FacesContext.getCurrentInstance();
		if(descripcionSimulacion != null && !descripcionSimulacion.trim().isEmpty()){
			try{
				Cliente cliente = clienteService.obtenerClientePorCodigoCentral(codigoCentral);
				if(cliente == null) {
					cliente = new Cliente();
					cliente.setCodigoCentral(clienteBean.getCodigoCentral());
					cliente.setNombreCliente(clienteBean.getNombreEmpresa());
					cliente.setDescripcion(clienteBean.getNombreEmpresa());
					cliente.setNumeroDocumento(clienteBean.getRuc());
					cliente.setTipoDocumento("R");
					cliente.setEstado(new BigDecimal(1));
					Calendar calendar = Calendar.getInstance();
					cliente.setFechaCreacion(new Timestamp(calendar.getTimeInMillis()));
					cliente.setFechaActualizacion(cliente.getFechaCreacion());
					clienteService.guardarCliente(cliente);
					cliente = clienteService.obtenerClientePorCodigoCentral(codigoCentral);
				}
				Simulacion simulacion = new Simulacion();
				simulacion.setCliente(cliente);
				simulacion.setEstado(new BigDecimal(1));
				simulacion.setNombreCliente(cliente.getNombreCliente());
				Calendar calendar = Calendar.getInstance();
				simulacion.setFechaCreacion(new Timestamp(calendar.getTimeInMillis()));
				simulacion.setFechaActualizacion(simulacion.getFechaCreacion());
				simulacion.setDescripcion(descripcionSimulacion);
				long idSimulacion = simulacionService.guardarSimulacion(simulacion);
				simulacion = simulacionService.obtenerSimulacionPorId(idSimulacion);
				
				DependencyEngine e = new DependencyEngine(new BasicEngineProvider());
				motorFormulasService.calcularFormulasRating(e, ratingBean, Constante.BALANCE_GENERAL);
				motorFormulasService.calcularFormulasRating(e, ratingBean, Constante.ESTADO_PERDIDAS_GANANCIAS);
				motorFormulasService.calcularFormulasRating(e, ratingBean, Constante.RATIOS);
				motorFormulasService.calcularFormulasRating(e, ratingBean, Constante.DATOS_ADICIONALES);
				motorFormulasService.calcularFormulasRating(e, ratingBean, Constante.DEUDA_INDIRECTA);
				motorFormulasService.registrarDetalleSimulacionRating(simulacion, e, ratingBean, Constante.BALANCE_GENERAL);
				motorFormulasService.registrarDetalleSimulacionRating(simulacion, e, ratingBean, Constante.ESTADO_PERDIDAS_GANANCIAS);
				motorFormulasService.registrarDetalleSimulacionRating(simulacion, e, ratingBean, Constante.RATIOS);
				motorFormulasService.registrarDetalleSimulacionRating(simulacion, e, ratingBean, Constante.DATOS_ADICIONALES);
				motorFormulasService.registrarDetalleSimulacionRating(simulacion, e, ratingBean, Constante.DEUDA_INDIRECTA);
				
				HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
				request.setAttribute("idSimulacion", String.valueOf(idSimulacion));
			}catch(Exception e){
				context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER005));
				LOGGER.debug(Constante.EXECPCION_ENCONTRADA + e.toString(), e);
				return null;
			}
		}else{
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, Constante.MSG_ERROR_PGER001));
			return null;
		}
		return "financiamiento-propuesto";
	}
	
	public String getNumeroDocumento() {
		return numeroDocumento;
	}

	public void setNumeroDocumento(String numeroDocumento) {
		this.numeroDocumento = numeroDocumento;
	}

	public int getTipoDocumento() {
		return tipoDocumento;
	}

	public void setTipoDocumento(int tipoDocumento) {
		this.tipoDocumento = tipoDocumento;
	}

	public String getCodigoCentral() {
		return codigoCentral;
	}

	public void setCodigoCentral(String codigoCentral) {
		this.codigoCentral = codigoCentral;
	}

	public boolean isMostrarInfo() {
		return mostrarInfo;
	}

	public void setMostrarInfo(boolean mostrarInfo) {
		this.mostrarInfo = mostrarInfo;
	}

	public RatingClienteBean getClienteBean() {
		return clienteBean;
	}

	public void setClienteBean(RatingClienteBean clienteBean) {
		this.clienteBean = clienteBean;
	}

	public String getDescripcionSimulacion() {
		return descripcionSimulacion;
	}

	public void setDescripcionSimulacion(String descripcionSimulacion) {
		this.descripcionSimulacion = descripcionSimulacion;
	}
	
	public String getMensajeLoading(){
		return Constante.MSG_EXITO_PGEX001;
	}
	
	
}
